/*
 * Modbus mutex for RTU.
 * Copyright (c) 2012  apleilx
 * All rights reserved.
 * no limite
 */

/* ----------------------- Platform includes --------------------------------*/

#include "os_obj.h"
#include "mbdef.h"

#if MB_OS_USED > 0

//如果每个对象只在单一的任务中操作，无需互斥锁

//static osMutexId     MutexObjmbCmd;
//static uint8_t       mbMutexCreated = 0;

//osMutexDef(MBCMD_Mutex);

/*****************************************************************************//*!
*
* @brief   modbus sync mutex creat.
*
* @param   none
*
* @return  none
*
* @ Pass/ Fail criteria: none
*****************************************************************************/
void mbOsSyncMutexCreat(void)
{

//    if(!mbMutexCreated)
//        MutexObjmbCmd = osMutexCreate (MutexObjmbCmd);
//
//    mbMutexCreated = 1;
}

/*****************************************************************************//*!
*
* @brief   modbus sync mutex pend.
*
* @param   none
*
* @return  none
*
* @ Pass/ Fail criteria: none
*****************************************************************************/
void mbOsSyncMutexPend(void)
{
    //OSMutexPend (&MutexObjmbCmd, 0,  OS_OPT_PEND_BLOCKING, &cpu_ts, &os_err);
//    osMutexWait(MutexObjmbCmd,1000);
}

/*****************************************************************************//*!
*
* @brief   modbus sync mutex post.
*
* @param   none
*
* @return  none
*
* @ Pass/ Fail criteria: none
*****************************************************************************/
void mbOsSyncMutexPost(void)
{

    //OSMutexPost (&MutexObjmbCmd,  OS_OPT_POST_NO_SCHED, &os_err);
//    osMutexRelease(MutexObjmbCmd);
}

#endif

/*****************************************************************************//*!
*
* @brief   modbus os delay.
*
* @param   none
*
* @return  none
*
* @ Pass/ Fail criteria: none
*****************************************************************************/
void mb_os_delay(uint32_t ms)
{
    osDelay(ms_ticks(ms));
}


/*****************************************************************************//*!
*
* @brief   modbus event snd.
*
* @param   none
*
* @return  none
*
* @ Pass/ Fail criteria: none
*****************************************************************************/
void mb_os_send(uint16_t event)
{
    osEventFlagsSet(os_obj.eid_mb, event);
}

/*****************************************************************************/ /*!
* @brief   rtu time end handle in lib.
*
* @param   none
*
* @return  none
*
* @ Pass/ Fail criteria: none
*****************************************************************************/
void lib_mbRtuTimerRun(mb_obj_type *mbObj)
{

    if( mbObj->bRtuTimerOn )
    {
        mbObj->RtuTimerCnt++;
        if(mbObj->RtuTimerCnt > mbObj->RtuTimerSv)
        {
            //关闭定时器
            mbObj->bRtuTimerOn = 0;
            mbObj->RtuTimerCnt = 0;

            if (MB_RX_RCV == mbObj->RcvSt)
            {
                //端口接收结束，告诉数据处理单元可以处理数据
                mbObj->RcvSt = MB_RX_RCVEND;
            }
        }
    }

    //报文结束保持计时
    if(mbObj->RunSt.bits.MasterMode)
    {
        if(mbObj->RcvSt == MB_RX_RCVEND)
        {
            if(mbObj->RtuRcvendKeepCnt == mbObj->RtuRcvendDelaySet) //只发一次
            {
                //发送任务事件
                if(mbObj->os_event_send)
                {
                    mbObj->os_event_send(mbObj->os_rtu_end_event);
                }
            }

            if(mbObj->RtuRcvendKeepCnt < 255)
                mbObj->RtuRcvendKeepCnt++;
        }
        else
        {
            mbObj->RtuRcvendKeepCnt = 0;
        }
    }
    else
    {
        if(mbObj->RcvSt == MB_RX_RCVEND)
        {
            if(mbObj->RtuRcvendKeepCnt == 0)
            {
                if(mbObj->os_event_send)
                {
                    mbObj->os_event_send(mbObj->os_rtu_end_event);
                }
            }

            if(mbObj->RtuRcvendKeepCnt < 255)
                mbObj->RtuRcvendKeepCnt++;
        }
        else
        {
            mbObj->RtuRcvendKeepCnt = 0;
        }
    }

    //超时中断 //仅供主机
    if(mbObj->RunSt.bits.MasterMode && (mbObj->RcvSt == MB_RX_WAIT))
    {
        mbObj->TimeOutCnt++;
        if( mbObj->TimeOutCnt > MMB_TIME_OUT_MS)
        {
            mbObj->TimeOutCnt = 0;
            mbObj->RcvSt = MB_RX_TIMEOUT;
            //发送任务事件
            if(mbObj->os_event_send)
            {
                mbObj->os_event_send(mbObj->os_timeout_event);
            }
        }
    }

    //活动状态计时
    if((mbObj->RcvSt == MB_RX_RCV) || (mbObj->SndSt == MB_TX_XMIT))
    {
        if(mbObj->active_keep_cnt < UINT16_MAX)
            mbObj->active_keep_cnt++;
        if(mbObj->active_keep_cnt > mbObj->active_keep_max)
            mbObj->active_keep_max = mbObj->active_keep_cnt;
    }
    else
    {
        mbObj->active_keep_cnt = 0;
    }

    //空闲计时
    if((mbObj->RcvSt == MB_RX_IDLE) && (mbObj->SndSt == MB_TX_IDLE))
    {
        if(mbObj->idle_time_cnt < UINT16_MAX)
            mbObj->idle_time_cnt ++;
    }
    else
    {
        mbObj->idle_time_cnt = 0;
    }
}
